#include "iotestwidget.h"
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QProcess>
#include <QTimer>
#include <QTime>
#include <QThread>
#include <unistd.h>
#include <fcntl.h>

IOTestWidget::IOTestWidget(QWidget *parent) : QWidget(parent)
{
    p_IOButton[0] = new QPushButton("OutIO1", this);
    p_IOButton[1] = new QPushButton("OutIO2", this);
    p_IOButton[2] = new QPushButton("OutIO3", this);
    p_IOButton[3] = new QPushButton("OutIO4", this);

    p_IOLabel[0] = new QLabel("InIO1", this);
    p_IOLabel[1] = new QLabel("InIO2", this);
    p_IOLabel[2] = new QLabel("InIO3", this);
    p_IOLabel[3] = new QLabel("InIO4", this);

    p_IOButton[0]->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    p_IOButton[1]->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    p_IOButton[2]->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    p_IOButton[3]->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    p_IOLabel[0]->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    p_IOLabel[1]->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    p_IOLabel[2]->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    p_IOLabel[3]->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    QHBoxLayout *pIOInLayout = new QHBoxLayout;
    pIOInLayout->addWidget(p_IOLabel[0]);
    pIOInLayout->addWidget(p_IOLabel[1]);
    pIOInLayout->addWidget(p_IOLabel[2]);
    pIOInLayout->addWidget(p_IOLabel[3]);

    QHBoxLayout *pIOOutLayout = new QHBoxLayout;
    pIOOutLayout->addWidget(p_IOButton[0]);
    pIOOutLayout->addWidget(p_IOButton[1]);
    pIOOutLayout->addWidget(p_IOButton[2]);
    pIOOutLayout->addWidget(p_IOButton[3]);

   QVBoxLayout *pMainLayout = new QVBoxLayout;
   pMainLayout->addLayout(pIOInLayout);
   pMainLayout->addLayout(pIOOutLayout);

   this->setLayout(pMainLayout);

    connect(p_IOButton[0], SIGNAL(clicked()), this, SLOT(dealiobut1()));
    connect(p_IOButton[1], SIGNAL(clicked()), this, SLOT(dealiobut2()));
    connect(p_IOButton[2], SIGNAL(clicked()), this, SLOT(dealiobut3()));
    connect(p_IOButton[3], SIGNAL(clicked()), this, SLOT(dealiobut4()));

    p_Timer = new QTimer;
    if(p_Timer != NULL) {
        connect(p_Timer, SIGNAL(timeout()), this, SLOT(checkiostate()));
        p_Timer->start(500);
    }

    p_IOButton[0]->setCheckable(true);
    p_IOButton[1]->setCheckable(true);
    p_IOButton[2]->setCheckable(true);
    p_IOButton[3]->setCheckable(true);

    p_IOLabel[0]->setStyleSheet("background-color:#DDDDDD");
    p_IOLabel[1]->setStyleSheet("background-color:#DDDDDD");
    p_IOLabel[2]->setStyleSheet("background-color:#DDDDDD");
    p_IOLabel[3]->setStyleSheet("background-color:#DDDDDD");

    this->gpioinit();
}

IOTestWidget::~IOTestWidget()
{
    if(p_Timer != NULL && p_Timer->isActive()) {
        p_Timer->stop();
    }

    this->gpiofree();
}

void IOTestWidget::writeiodev(const char *context, const char *devfile)
{
    int fd = ::open(devfile, O_WRONLY);

    if(fd > 0) {
        ::write(fd, context, strlen(context));
        ::close(fd);
    }
}

int IOTestWidget::readiodev(const char *devfile)
{
    unsigned char iostate;

    int fd = ::open(devfile, O_RDONLY);

    if(fd > 0) {
        ::read(fd, &iostate, 1);
        ::close(fd);
        return iostate - 48;
    }

    return -1;
}

void IOTestWidget::gpioinit()
{
    this->writeiodev("48", "/sys/class/gpio/export");
    this->writeiodev("in", "/sys/class/gpio/gpio48/direction");
    this->writeiodev("49", "/sys/class/gpio/export");
    this->writeiodev("in", "/sys/class/gpio/gpio49/direction");
    this->writeiodev("50", "/sys/class/gpio/export");
    this->writeiodev("in", "/sys/class/gpio/gpio50/direction");
    this->writeiodev("51", "/sys/class/gpio/export");
    this->writeiodev("in", "/sys/class/gpio/gpio51/direction");

    this->writeiodev("52", "/sys/class/gpio/export");
    this->writeiodev("high", "/sys/class/gpio/gpio52/direction");
    this->writeiodev("62", "/sys/class/gpio/export");
    this->writeiodev("high", "/sys/class/gpio/gpio62/direction");
    this->writeiodev("63", "/sys/class/gpio/export");
    this->writeiodev("high", "/sys/class/gpio/gpio63/direction");
}

void IOTestWidget::gpiofree()
{
//    this->writeiodev("48", "/sys/class/gpio/unexport");
//    this->writeiodev("49", "/sys/class/gpio/unexport");
//    this->writeiodev("50", "/sys/class/gpio/unexport");
//    this->writeiodev("51", "/sys/class/gpio/unexport");

//    this->writeiodev("52", "/sys/class/gpio/unexport");
//    this->writeiodev("62", "/sys/class/gpio/unexport");
//    this->writeiodev("63", "/sys/class/gpio/unexport");
}

void IOTestWidget::checkiostate()
{
    int iostate = this->readiodev("/sys/class/gpio/gpio48/value");
    if(iostate == 0) {
        p_IOLabel[0]->setStyleSheet("background-color:#0000ff");
    } else {
        p_IOLabel[0]->setStyleSheet("background-color:#dddddd");
    }

    iostate = this->readiodev("/sys/class/gpio/gpio49/value");
    if(iostate == 0) {
        p_IOLabel[1]->setStyleSheet("background-color:#0000ff");
    } else {
        p_IOLabel[1]->setStyleSheet("background-color:#dddddd");
    }

    iostate = this->readiodev("/sys/class/gpio/gpio50/value");
    if(iostate == 0) {
        p_IOLabel[2]->setStyleSheet("background-color:#0000ff");
    } else {
        p_IOLabel[2]->setStyleSheet("background-color:#dddddd");
    }

    iostate = this->readiodev("/sys/class/gpio/gpio51/value");
    if(iostate == 0) {
        p_IOLabel[3]->setStyleSheet("background-color:#0000ff");
    } else {
        p_IOLabel[3]->setStyleSheet("background-color:#dddddd");
    }

    p_Timer->start(500);
}

void IOTestWidget::dealiobut1()
{
    if(p_IOButton[0]->isChecked()) {
        this->writeiodev("0", "/sys/class/gpio/gpio52/value");
    } else {
        this->writeiodev("1", "/sys/class/gpio/gpio52/value");
    }
}

void IOTestWidget::dealiobut2()
{
    if(p_IOButton[1]->isChecked()) {
        this->writeiodev("0", "/sys/class/gpio/gpio62/value");
    } else {
        this->writeiodev("1", "/sys/class/gpio/gpio62/value");
    }
}

void IOTestWidget::dealiobut3()
{
    if(p_IOButton[2]->isChecked()) {
        this->writeiodev("0", "/sys/class/gpio/gpio63/value");
    } else {
        this->writeiodev("1", "/sys/class/gpio/gpio63/value");
    }
}

void IOTestWidget::dealiobut4()
{
    qDebug("but4");
}
